package btb.ui;

import de.matthiasmann.twl.Alignment;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.CallbackWithReason;
import de.matthiasmann.twl.Label;
import de.matthiasmann.twl.ListBox;
import de.matthiasmann.twl.ListBox.CallbackReason;
import de.matthiasmann.twl.TextArea;
import de.matthiasmann.twl.ResizableFrame.ResizableAxis;
import de.matthiasmann.twl.model.SimpleChangableListModel;
import de.matthiasmann.twl.textarea.SimpleTextAreaModel;
import btb.engine.CDisplayTask;
import btb.engine.CTaskMessenger;
import btb.engine.CDisplayTask.NGuiState;
import btb.engine.CSession;
import btb.engine.CSession.NSessionProfile;
import btb.net.CChannel.NChannelProfile;
import btb.net.CNetwork.NUpdateChannelList;
import btb.net.CNetworkEvent;
import btb.util.CLogger;

public class CGuiHub extends AGuiObject
{
	private Label lblSessions;
	private Label lblChannels;
	private Label lblUsers;
	
	// [Development]: The listbox objects with <String> are under development - or rather, the things they're supposed to hold are.
	private ListBox<NSessionProfile> lstSessions;
	private ListBox<NChannelProfile> lstChannels;
	private ListBox<String> lstUsers;
	
	private TextArea txtProfile;
	private SimpleTextAreaModel txtProfModel;
	
	public CChatFrame frmHubChat;
	
	private Button btnJoin;
	private Button btnRefresh;
	private Button btnLogout;
	private Button btnExit;
	
	private CallbackWithReason<ListBox.CallbackReason> lstSessionsCallback = null;
	private Runnable btnRefreshCallback = null;
	private Runnable btnLogoutCallback = null;
	private Runnable btnExitCallback = null;
	
	private String username;
	
	public CGuiHub(CDisplayTask _parent)
	{
		super(_parent);
	}
	
	@Override
	public void initializeGUI(int _guiDisplayOption)
	{
		initializeDisplay(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, "Beat the Bard Prototype", BTB_THEME_02_FILEPATH, _guiDisplayOption);
	}
	
	@Override
	protected void initializeWidgets(int _guiDisplayOption)
	{
		username = "default_user";
		
		lblSessions 	= new Label();
		lblChannels		= new Label();
		lblUsers 		= new Label();
		
		lstSessions 	= new ListBox<NSessionProfile>();
		lstChannels 	= new ListBox<NChannelProfile>();
		lstUsers 		= new ListBox<String>();
	
		txtProfile		= new TextArea();
		txtProfModel	= new SimpleTextAreaModel();
				
		frmHubChat		= new CChatFrame(this.username);
		
		btnJoin			= new Button();
		btnRefresh		= new Button();
		btnLogout		= new Button();
		btnExit			= new Button();
	}

	@Override
	//@SuppressWarnings("unchecked")
	protected void addWidgets(int _guiDisplayOption)
	{
		addNewLabel(this.lblSessions, "gamelabel", "Sessions (All)");
		addNewLabel(this.lblChannels, "gamelabel", "Channel List");
		addNewLabel(this.lblUsers, "gamelabel", "Users");

		addNewListBox(this.lstSessions, "gamelistbox");
		addNewListBox(this.lstChannels, "gamelistbox");
		addNewListBox(this.lstUsers, "gamelistbox");
		
		addNewTextArea(this.txtProfile, "gametextarea", "", this.txtProfModel);
		
		addNewWidget(this.frmHubChat, "chatframe");
		
		addNewButton(this.btnJoin, "submitbutton", "Join");
		addNewButton(this.btnRefresh, "submitbutton", "Refresh Lists");
		addNewButton(this.btnLogout, "submitbutton", "Logout");
		addNewButton(this.btnExit, "submitbutton", "Exit");
	}

	@Override
	protected void setLayout(int _guiDisplayOption)
	{
		// [Listbox labels]
		resizeWidgetRelativeToWindow(this.lblSessions, 8f / 32, 1f / 32, true);
		copyWidgetSize(this.lblSessions, this.lblChannels);
		copyWidgetSize(this.lblSessions, this.lblUsers);
		placeWidgetInEqualRow(this.lblSessions, 1, 3, 2.5f / 32, true);
		placeWidgetInEqualRow(this.lblChannels, 2, 3, this.lblSessions.getY(), false);
		placeWidgetInEqualRow(this.lblUsers, 3, 3, this.lblSessions.getY(), false);
		this.lblSessions.setAlignment( Alignment.CENTER );
		this.lblChannels.setAlignment( Alignment.CENTER );
		this.lblUsers.setAlignment( Alignment.CENTER );
		
		// [Listboxes]
		resizeWidgetRelativeToWindow(this.lstSessions, 8f / 32, 8f / 32, false);
		copyWidgetSize(this.lstSessions, this.lstChannels);
		copyWidgetSize(this.lstSessions, this.lstUsers);
		placeWidgetInEqualRow(this.lstSessions, 1, 3, 3.5f / 32, true);
		placeWidgetInEqualRow(this.lstChannels, 2, 3, this.lstSessions.getY(), false);
		placeWidgetInEqualRow(this.lstUsers, 3, 3, this.lstSessions.getY(), false);
		
		// [Profile TextArea]
		resizeWidgetRelativeToWindow(this.txtProfile, 9f / 32, 14.5f / 32, false);
		placeWidgetAgainstWindow(this.txtProfile, 2f / 32, 13f / 32, false, false);
		
		// [Chat Frame]
		resizeWidgetRelativeToWindow(this.frmHubChat, 18f / 32, 14.5f / 32, false);
		placeWidgetAgainstWindow(this.frmHubChat, 12f / 32, 13f / 32, false, false);
		this.frmHubChat.setResizableAxis(ResizableAxis.NONE);
		
		// [Buttons]
		resizeWidgetRelativeToWindow(this.btnJoin, 8f / 32, 1.5f / 32, true);
		copyWidgetSize(this.btnJoin, this.btnRefresh);
		copyWidgetSize(this.btnJoin, this.btnLogout);
		copyWidgetSize(this.btnJoin, this.btnExit);
		placeWidgetInEqualRow(this.btnJoin, 1, 4, 29f / 32, true);
		placeWidgetInEqualRow(this.btnRefresh, 2, 4, this.btnJoin.getY(), false);
		placeWidgetInEqualRow(this.btnLogout, 3, 4, this.btnJoin.getY(), false);
		placeWidgetInEqualRow(this.btnExit, 4, 4, this.btnJoin.getY(), false);
		
		populateLists();
	}

	@Override
	protected void resetPage(int _guiDisplayOption)
	{
		
	}
	
	@Override
	protected void removeCallBacks(int _guiDisplayOption)
	{
		if(lstSessionsCallback != null)
			lstSessions.removeCallback(lstSessionsCallback);
		if(btnRefreshCallback != null)
			btnRefresh.removeCallback(btnRefreshCallback);
		if(btnLogoutCallback != null)
			btnLogout.removeCallback(btnLogoutCallback);
		if(btnExitCallback != null)
			btnExit.removeCallback(btnExitCallback);
	}
	
	@Override
	protected void addCallBacks(int _guiDisplayOption)
	{
		lstSessionsCallback = new CallbackWithReason<ListBox.CallbackReason>()
		{
			@Override
			public void callback(CallbackReason cbreason)
			{
				if(cbreason == CallbackReason.SET_SELECTED || cbreason == CallbackReason.MOUSE_CLICK)
				{
					NSessionProfile nsp;
					
					try
					{
						nsp = lstSessions.getModel().getEntry(lstSessions.getSelected());
					}
					catch(Exception e)
					{
						nsp = null;
						System.out.println("Wrong data type in lstSessions!");
					}
					
					if(nsp != null)
						displaySessionInfo(nsp);
				}
			}	
		};
		
		btnRefreshCallback = new Runnable()
		{	
			public void run()
			{
				populateLists();			
			}
		};
		
		btnLogoutCallback = new Runnable()
		{	
			public void run()
			{
				String networkEventString = "logout%";
				CNetworkEvent networkEvent = new CNetworkEvent(this, CNetworkEvent.CNE_LOGOUT_EVENT, networkEventString);
				CTaskMessenger mBox = callingTask.getMailbox();
				mBox.push(CTaskMessenger.TASK_MCLIENT, networkEvent);
				
				callingTask.switchGuiState(NGuiState.LOGIN_PAGE);			
			}
		};
		
		btnExitCallback = new Runnable()
		{	
			public void run()
			{
				System.out.println(callingTask.getParentTask().getClass().getName());
				callingTask.getParentTask().kill();
			}
		};
		
		this.lstSessions.addCallback(lstSessionsCallback);
		this.btnRefresh.addCallback(btnRefreshCallback);
		this.btnLogout.addCallback(btnLogoutCallback);
		this.btnExit.addCallback(btnExitCallback);
	}
	
	public void populateLists()
	{
		//populateSessionList();
		populateChannelList(null);
	}
	
	public void populateSessionList()
	{
		// TESTING CODE
		
		SimpleChangableListModel<NSessionProfile> slm = new SimpleChangableListModel<NSessionProfile>();
		
		for(int i = 0; i < 3; i++)
		{
			NSessionProfile nsp = (NSessionProfile) new CSession("Session #" + i).getProfile();
			slm.addElement(nsp);
		}
		
		lstSessions.setModel(slm);
		
		// TESTING CODE ENDS HERE
	}
	
	public void populateChannelList(NUpdateChannelList _clist)
	{
		if(_clist != null)
		{
			SimpleChangableListModel<NChannelProfile> slm = new SimpleChangableListModel<NChannelProfile>();
			
			for(int i = 0; i < _clist.channels.size(); i++)
			{
				slm.addElement((NChannelProfile)_clist.channels.get(i));
			}
			lstChannels.setModel(slm);
		}
		else
		{
			CLogger.cond_trace("hub gui", "Attempting to populate channel list...");
			NUpdateChannelList clist = new NUpdateChannelList();
			CNetworkEvent netevent = new CNetworkEvent(callingTask, CNetworkEvent.CNE_CHAT_UPDATE, clist);
			callingTask.getMailbox().push(CTaskMessenger.TASK_CCLIENT, netevent);
		}
	}
	
	public void displaySessionInfo(NSessionProfile sessionProfile)
	{					
		txtProfModel.setText(sessionProfile.snapShot());
	}
	
	public void displayChannelInfo(NChannelProfile channelProfile)
	{
		txtProfModel.setText(channelProfile.snapShot());
	}
}
